package com.m.job.compents;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.m.job.logs.model.MJobInstanceHistory;
import com.m.job.logs.service.MJobInstanceHistoryService;
import com.m.utils.IdUtil;
import org.springframework.stereotype.Component;

import com.client.job.core.model.MJob;
import com.client.job.core.model.MJobInstance;

import javax.annotation.Resource;

/**
 * @author mengxiangzhong
 * @des 同一修改
 * @date 2021年9月16日
 */

@Component
public class JobAndInstanceCompent {

    @Resource
    private SocketJobForCLientComponent client;

    @Resource
    private MJobInstanceHistoryService mJobInstanceHistoryService;

    /**
     * 暂停实例
     *
     * @param delMjobList     被暂停的Job
     * @param delInstanceLit  被暂停的实例
     * @param updMjobList     需要重置的Job
     * @param updInstanceList 需要重置的实例
     * @throws IOException
     */
    public void stopInstances(List<MJob> delMjobList, List<MJobInstance> delInstanceLit, List<MJob> updMjobList,
                              List<MJobInstance> updInstanceList) throws IOException {
        if (delMjobList != null && !delMjobList.isEmpty()) {
            client.delJobInstance(delMjobList, delInstanceLit);
        }
        if (updMjobList != null && !updMjobList.isEmpty()) {
            client.updAppCounts(updMjobList, updInstanceList);
        }
        //添加开启实例的日志
        addInstanceLogs("修改暂停的实例", "需要变更的实例", delInstanceLit, updInstanceList);
    }

    /**
     * 开启实例
     *
     * @param stopInstanceList   需要被开启的实例
     * @param updJobList         需要重置的Job
     * @param updJobInstanceList 需要重置的实例
     */
    public void startInstances(List<MJobInstance> stopInstanceList, List<MJob> updJobList,
                               List<MJobInstance> updJobInstanceList) {
        if (updJobList != null && !updJobList.isEmpty()) {
            client.updAppCounts(updJobList, updJobInstanceList);
        }
        //添加开启实例的日志
        addInstanceLogs("开启的实例", "需要变更的实例", stopInstanceList, updJobInstanceList);

    }

    /**
     * 复制一个实例
     *
     * @param jobInstance     复制的实例
     * @param mJob            复制的Job
     * @param updInstanceList 需要重置的实例
     */
    public void copyInstance(MJobInstance jobInstance, MJob mJob, List<MJobInstance> updInstanceList) {
        client.updAppCounts(Arrays.asList(mJob), updInstanceList);
        //添加开启实例的日志
        addInstanceLogs("被复制的实例", "需要变更的实例", Arrays.asList(jobInstance), updInstanceList);
    }

    /**
     * 新增一个实例
     *
     * @param mJobInstance    被新增的实例
     * @param mJob            新增实例的Job
     * @param updInstanceList 需要重置的实例
     */
    public void addNewInstance(MJobInstance mJobInstance, MJob mJob, List<MJobInstance> updInstanceList) {
        client.updAppCounts(Arrays.asList(mJob), updInstanceList);
        //添加开启实例的日志
        addInstanceLogs("新增的实例", "需要变更的实例", Arrays.asList(mJobInstance), updInstanceList);
    }

    /**
     * 实例注册
     *
     * @param registJob          注册的Job
     * @param registInstanceList 注册的实例
     * @param updJobList         需要重置的Job
     * @param runIanceList    需要重置的实例
     */
    public void registerInstanceList(MJob registJob, List<MJobInstance> registInstanceList, List<MJob> updJobList,
                                     List<MJobInstance> runIanceList) {
        if (updJobList == null || updJobList.isEmpty()) {
            //该服务所有的Job已经被停止
            return;
        }
        client.updAppCounts(updJobList, runIanceList);
        //添加开启实例的日志
        List<String> instanceIdList = registInstanceList.stream().map(MJobInstance::getMachineId).collect(Collectors.toList());
        List<MJobInstance> upList = new ArrayList<>();
        runIanceList.forEach( o ->{
        	if(!instanceIdList.contains(o.getMachineId())) {
        		upList.add(o);
        	}
        });
        addInstanceLogs("注册的实例", "需要变更的实例", registInstanceList, upList);
    }

    /**
     * 服务宕机
     *
     * @param dwonInstanceList 该服务上所有的实例
     * @param updJobList       需要重置的Job
     * @param updInstanceList  需要重置的实例
     */
    public void serverDown(List<MJobInstance> dwonInstanceList, List<MJob> updJobList, List<MJobInstance> updInstanceList) {
        if (updJobList == null || updJobList.isEmpty()) {
            //服务上无运行实例或者无其他运行实例
            return;
        }
        client.updAppCounts(updJobList, updInstanceList);
        //添加开启实例的日志
        addInstanceLogs("宕机的实例", "需要变更的实例", dwonInstanceList, updInstanceList);
    }

    /**
     * 添加实例日志
     * @param remark1
     * @param remark2
     * @param list1
     * @param list2
     */
    private void addInstanceLogs(String remark1, String remark2,List<MJobInstance> list1,List<MJobInstance> list2) {
        //插入实例变更日志
        
        List<String>  instanceInfo1 = new ArrayList<>();
        List<String>  instanceInfo2 = new ArrayList<>();
        List<String>  instanceIds1 = new ArrayList<>();
        List<String>  instanceIds2 = new ArrayList<>();
        Set<String>  jobIds = new HashSet<>();
        for(MJobInstance m1 : list1) {
        	instanceInfo1.add(m1.getMachineIp()+":"+m1.getPort()+ m1.getBasePath());
        	instanceIds1.add(m1.getMachineId());
        	jobIds.add(m1.getJobId());
        }
        for(MJobInstance m2 : list2) {
        	instanceInfo2.add(m2.getMachineIp()+":"+m2.getPort()+ m2.getBasePath());
        	instanceIds2.add(m2.getMachineId());
        	jobIds.add(m2.getJobId());
        }

        MJobInstanceHistory history = MJobInstanceHistory.builder()
        							.intanceHistoryId(IdUtil.genId())
        							.dealTime(new Date())
        							.remark1(remark1+":"+String.join(",", instanceInfo1))
        							.remark2(remark2+":"+String.join(",", instanceInfo2))
        							.instanceIds(String.join(",", instanceIds1)+" / "+String.join(",", instanceIds2) )
        							.jobIds(String.join(",", jobIds))
        							.build();
        
      mJobInstanceHistoryService.insertSelective(history);
    }

}
